// Copyright(c) 2008 Tri Tech Information Systems Inc. 
// Distributed under the Boost Software License, Version 1.0.
//     (See accompanying file ../../LICENSE_1_0.txt or copy at
//           http://www.boost.org/LICENSE_1_0.txt)
//     
#include <llvm/AbstractTypeUser.h>
#include <boost/python.hpp>
#include <pyxx/pointer.h>

/*
 * I don't really like this...
 *
 * Essentially we don't ever try to cleanup any Value subclasses
 * As long as you do thing correctly, thats not a problem
 * Ha HA...
 *
 *
 * llvm will basically attempt to delete all the value classes
 * hooked into the system. This means python doesn't really need
 * to delete them itself.
 *
 * However, beware using dangling references...
 *
 * I'd like to do something better but I'm not sure what I can do...
 * As far as I've been able to determine I can't be notified or prevent
 * the destruction of an object
 */

template< typename ValueType >
struct ValuePointer 
{
    typedef ValueType element_type;
    typedef ValuePointer<element_type> this_type;

    ValueType * m_ptr;

    ValuePointer(element_type * type) :
        m_ptr(type)
    {}

    static void install()
    {
        add_pointer_handler<ValueType>( &this_type::from_ptr );
    }

    static boost::python::object from_ptr(const void * vptr)
    {
        using namespace boost::python;
        void * fvptr = const_cast<void*>(vptr);
        return object( this_type( reinterpret_cast<element_type*>(fvptr) ) );
    }
};

template<typename ValueType>
ValueType * get_pointer(const ValuePointer<ValueType> & ptr)
{
    return ptr.m_ptr;
}


namespace boost
{
    namespace python
    {
        template<typename ValueType>
        struct pointee< ValuePointer<ValueType> >
        {
            typedef ValueType type;
        };
        
    }
}
